package com.rui.cn.provider.service.redis.impl;

import com.rui.cn.enums.RedisExpireTime;
import com.rui.cn.provider.service.redis.RedisHelper;
import com.rui.cn.provider.service.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
*@description：redis常用方法实现类
*@author：[zhangruilin]
*@className：RedisServiceImpl
*@time：2018/5/18-14:17
**/
@Service
public class RedisServiceImpl implements RedisService {

	@Resource
	private RedisTemplate<String, Object> redisTemplate;

	@Resource
	private StringRedisTemplate stringRedisTemplate;

	/**
	 * 删除缓存<br>
	 * 根据key精确匹配删除
	 * @param key
	 */
	public void del(String... key) {
		RedisHelper.del(redisTemplate, key);
	}

	/**
	 * 批量删除<br>
	 * （该操作会执行模糊查询，请尽量不要使用，以免影响性能或误删）
	 * @param pattern
	 */
	public void batchDel(String... pattern) {
		RedisHelper.batchDel(redisTemplate, pattern);
	}

	/**
	 * 取得缓存（int型）
	 * @param key
	 * @return
	 */
	public Integer getInt(String key) {
		return RedisHelper.getInt(stringRedisTemplate, key);
	}

	/**
	 * 取得缓存（字符串类型）
	 * @param key
	 * @return
	 */
	public String getStr(String key) {
		return RedisHelper.getStr(stringRedisTemplate, key);
	}

	/**
	 * 取得缓存（字符串类型）
	 * @param key
	 * @return
	 */
	public String getStr(String key, boolean retain) {
		return RedisHelper.getStr(redisTemplate, stringRedisTemplate, key, retain);
	}

	/**
	 * 获取缓存<br>
	 * 注：基本数据类型(Character除外)，请直接使用get(String key, Class<T> clazz)取值
	 * @param key
	 * @return
	 */
	public Object getObj(String key) {
		return RedisHelper.getObj(redisTemplate, key);
	}

	/**
	 * 获取缓存<br>
	 * 注：java 8种基本类型的数据请直接使用get(String key, Class<T> clazz)取值
	 * @param key
	 * @param retain 是否保留
	 * @return
	 */
	public Object getObj(String key, boolean retain) {
		return RedisHelper.getObj(redisTemplate, key, retain);
	}

	/**
	 * 获取缓存<br>
	 * 注：该方法暂不支持Character数据类型
	 * @param key key
	 * @param clazz 类型
	 * @return
	 */
	public <T> T get(String key, Class<T> clazz) {
		return RedisHelper.get(redisTemplate, key, clazz);
	}

	/**
	 * 获取缓存json对象<br>
	 * @param key key
	 * @param clazz 类型
	 * @return
	 */
	public <T> T getJson(String key, Class<T> clazz) {
		return RedisHelper.getJson(stringRedisTemplate, key, clazz);
	}

	/**
	 * 将value对象写入缓存
	 * @param key
	 * @param value
	 * @param time 失效时间(秒)
	 */
	public void set(String key, Object value, RedisExpireTime time) {
		RedisHelper.set(redisTemplate,  stringRedisTemplate,key, value, time);
	}

	/**
	 * 将value对象以JSON格式写入缓存
	 * @param key
	 * @param value
	 * @param time 失效时间(秒)
	 */
	public void setJson(String key, Object value, RedisExpireTime time) {
		RedisHelper.setJson(stringRedisTemplate, key, value, time);
	}

	/**
	 * 更新key对象field的值
	 * @param key 缓存key
	 * @param field 缓存对象field
	 * @param value 缓存对象field值
	 */
	public void setJsonField(String key, String field, String value) {
		RedisHelper.setJsonField(stringRedisTemplate, key, field, value);
	}

	/**
	 * 递减操作
	 * @param key
	 * @param by
	 * @return
	 */
	public double decr(String key, double by) {
		return RedisHelper.decr(redisTemplate, key, by);
	}

	/**
	 * 递增操作
	 * @param key
	 * @param by
	 * @return
	 */
	public double incr(String key, double by) {
		return RedisHelper.incr(redisTemplate, key, by);
	}

	/**
	 * 获取double类型值
	 * @param key
	 * @return
	 */
	public double getDouble(String key) {
		return RedisHelper.getDouble(stringRedisTemplate, key);
	}

	/**
	 * 设置double类型值
	 * @param key
	 * @param value
	 * @param time 失效时间(秒)
	 */
	public void setDouble(String key, double value, RedisExpireTime time) {
		RedisHelper.setDouble(stringRedisTemplate, key, value, time);
	}

	/**
	 * 设置double类型值
	 * @param key
	 * @param value
	 * @param time 失效时间(秒)
	 */
	public void setInt(String key, int value, RedisExpireTime time) {
		RedisHelper.setInt(stringRedisTemplate, key, value, time);
	}

	/**
	 * 将map写入缓存
	 * @param key
	 * @param map
	 * @param time 失效时间(秒)
	 */
	public <T> void setMap(String key, Map<String, T> map, RedisExpireTime time) {
		RedisHelper.setMap(redisTemplate, key, map, time);
	}

	/**
	 * 将map写入缓存
	 * @param key
	 * @param map
	 * @param time 失效时间(秒)
	 */
	public <T> void setMap(String key, T obj, RedisExpireTime time) {
		RedisHelper.setMap(redisTemplate, key, obj, time);
	}

	/**
	 * 向key对应的map中添加缓存对象
	 * @param key
	 * @param map
	 */
	public <T> void addMap(String key, Map<String, T> map) {
		RedisHelper.addMap(redisTemplate, key, map);
	}

	/**
	 * 向key对应的map中添加缓存对象
	 * @param key cache对象key
	 * @param field map对应的key
	 * @param value 值
	 */
	public void addMap(String key, String field, String value) {
		RedisHelper.addMap(redisTemplate, key, field, value);
	}

	/**
	 * 向key对应的map中添加缓存对象
	 * @param key cache对象key
	 * @param field map对应的key
	 * @param obj 对象
	 */
	public <T> void addMap(String key, String field, T obj) {
		RedisHelper.addMap(redisTemplate, key, field, obj);
	}

	/**
	 * 获取map缓存
	 * @param key
	 * @param clazz
	 * @return
	 */
	public <T> Map<String, T> mget(String key, Class<T> clazz) {
		return RedisHelper.mget(redisTemplate, key, clazz);
	}

	/**
	 * 获取map缓存
	 * @param key
	 * @param clazz
	 * @return
	 */
	public <T> T getMap(String key, Class<T> clazz) {
		return RedisHelper.getMap(redisTemplate, key, clazz);
	}

	/**
	 * 获取map缓存中的某个对象
	 * @param key
	 * @param field
	 * @param clazz
	 * @return
	 */
	public <T> T getMapField(String key, String field, Class<T> clazz) {
		return RedisHelper.getMapField(redisTemplate, key, field, clazz);
	}

	/**
	 * 删除map中的某个对象
	 * @param <T>
	 * @param key map对应的key
	 * @param field map中该对象的key
	 */
	public <T> void delMapField(String key, Class<T> clazz, Object... field) {
		RedisHelper.delMapField(redisTemplate, key, field, clazz);
	}

	/**
	 * 指定缓存的失效时间
	 * @date 2016年8月14日
	 * @param key 缓存KEY
	 * @param time 失效时间(秒)
	 */
	public void expire(String key, RedisExpireTime time) {
		RedisHelper.expire(redisTemplate, key, time);
	}

	/**
	 * 短信缓存
	 * @param key
	 * @param value
	 * @param time
	 */
	public void setIntForPhone(String key, Object value, int time) {
		RedisHelper.setIntForPhone(stringRedisTemplate, key, value, time);
	}

	/**
	 * 模糊查询keys
	 * @param pattern
	 * @return
	 */
	public Set<String> keys(String pattern) {
		return RedisHelper.keys(redisTemplate, pattern);
	}
	
	/**
	 * 获取list集合
	 */
	public <T> List<T> getList(String key ,Class<T> clazz){
		return RedisHelper.getList(redisTemplate, key, clazz) ;
	}
	
	/**
	 * 获取指定开始结束的list集合
	 */
	public <T> List<T> getList(String key ,Class<T> clazz,Long start ,Long end){
		return RedisHelper.getList(redisTemplate, key, clazz, start, end) ;
	}
	
	/**
	 * 添加list
	 * @param key
	 * @param list
	 */
	public <T> void setList(String key,List<T> list ,RedisExpireTime time){
		RedisHelper.setList(redisTemplate, key, list, time);
	}
	
	/**
	 * 获取集合的长度
	 * @param key
	 */
	public Long getListSize(String key){
		return RedisHelper.getListSize(redisTemplate, key);
	}
	@Override
	public void delMapFiled(String key, String filed) {
		RedisHelper.delMapFiled(redisTemplate,key,filed);
		
	}

	@Override
	public <T, E> void updOrAddForHash(String key, String hkey, Class<T> clazz, E entity,String delKey,String delHkey) throws Exception{
		//实例化dto
		T dto = clazz.newInstance();
		//拷贝数据
		BeanUtils.copyProperties(entity, dto);
		//删除原本的数据
		if(StringUtils.isNotBlank(delKey) && StringUtils.isNotBlank(delHkey)){
			RedisHelper.delMapFiled(redisTemplate, delKey, delHkey);
		}
		//新增或保存到redis
		RedisHelper.addMap(redisTemplate, key, hkey, dto);
	}
}
